package cn.lili.modules.order.cart.render.impl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.order.cart.entity.dto.MemberCouponDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.RenderStepEnums;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.order.cart.render.util.PromotionPriceUtil;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.dto.SiteMarketingCost;
import cn.lili.modules.promotion.client.PromotionsClient;
import cn.lili.modules.promotion.client.ReturnActivityClient;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.ReturnActivityUser;
import cn.lili.modules.promotion.entity.enums.CouponTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
import cn.lili.modules.promotion.entity.vos.MemberCouponVO;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 购物促销信息渲染实现
 *
 * @author Chopper
 * @since 2020-07-02 14:47
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CouponRender implements CartRenderStep {

    private final PromotionsClient promotionsClient;

    private final ReturnActivityClient returnActivityClient;

    @Override
    public RenderStepEnums step() {
        return RenderStepEnums.COUPON;
    }

    @Override
    public void render(TradeDTO tradeDTO) {

        //优惠券列表
        this.renderCouponRule(tradeDTO);
        //主要渲染各个优惠的价格
        this.renderCoupon(tradeDTO);
    }


    /**
     * 渲染优惠券规则
     *
     * @param tradeDTO 交易dto
     */
    private void renderCouponRule(TradeDTO tradeDTO) {
        // 清除购物车信息中，可使用的优惠券列表和不可使用的优惠券列表
        tradeDTO.removeCoupon();

        // 免税商品不能使用优惠券
        if (StringUtils.isNotEmpty(tradeDTO.getAuthName()) && StringUtils.isNotEmpty(tradeDTO.getAuthCardNo())) {
            return;
        }

        boolean isMh = false;
        boolean isGreenSecurities = false;
        for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
            if (StringUtils.isNotEmpty(cartSkuVO.getGoodsSku().getMhId())) {
                isMh = true;
            }

            if (null != cartSkuVO.getIsGreenSecurities() && cartSkuVO.getIsGreenSecurities()) {
                isGreenSecurities = true;
            }
        }
        if (isMh) {
            return;
        }

        if (null != tradeDTO.getPromotionType()) {
            return;
        }

        //获取最新会员优惠券
        log.info("---memberCouponList begin");
        log.info("---tradeDTO.getMemberId()--{}",tradeDTO.getMemberId());
        List<MemberCoupon> memberCouponList = promotionsClient.getMemberCoupons(tradeDTO.getMemberId());
        log.info("---memberCouponList end---{}", JSON.toJSONString(memberCouponList));

        //由于优惠券服务缓存信息，所以这里需要进行时间有消息判定
        memberCouponList = memberCouponList.stream()
                .filter(item -> item.getStartTime().before(new Date()) && item.getEndTime().after(new Date()))
                .toList();


        // 为空，则将购物车的优惠券清空处理
        if (memberCouponList.isEmpty()) {
            tradeDTO.setPlatformCoupon(null);
            tradeDTO.setStoreCoupons(new HashMap<>());
        }
        // 会员优惠券列表不为空，则进行优惠券的过滤
        else {
            this.invalidCouponRemoval(tradeDTO, memberCouponList);
        }
        //判定优惠券是否可用
        memberCouponList.forEach(memberCoupon -> available(tradeDTO, memberCoupon));

        if (!isGreenSecurities) {
            List<ReturnActivityUser> returnActivityUserList = returnActivityClient.getList(tradeDTO.getMemberId());
            if (!returnActivityUserList.isEmpty()) {
                returnActivityUserList.forEach(returnActivityUser -> returnActivityUser.setReason("购物车中没有满足绿色积分全返券使用范围的全返券"));
            }
            tradeDTO.setCantReturnActivityUserList(returnActivityUserList);
        }
    }

    /**
     * 将 无效/过期 优惠券移除
     *
     * @param tradeDTO         交易dto
     * @param memberCouponList 会员优惠券列表
     */
    private void invalidCouponRemoval(TradeDTO tradeDTO, List<MemberCoupon> memberCouponList) {
        // 如果使用了平台优惠券
        if (tradeDTO.getPlatformCoupon() != null && tradeDTO.getPlatformCoupon().getMemberCoupon() != null) {
            // 如果购物车的优惠券不包含在最新的优惠券列表中，则将购物车的优惠券置空
            boolean exist = memberCouponList.stream().anyMatch(i -> i.getId().equals(tradeDTO.getPlatformCoupon().getMemberCoupon().getId()));
            if (!exist) {
                tradeDTO.setPlatformCoupon(null);
            }
        }
        // 如果使用了店铺优惠券
        if (!tradeDTO.getStoreCoupons().isEmpty()) {
            for (Map.Entry<String, MemberCouponDTO> entry : tradeDTO.getStoreCoupons().entrySet()) {
                // 如果购物车的优惠券不包含在最新的优惠券列表中，则将购物车的优惠券移除
                if (entry.getValue().getMemberCoupon() != null && memberCouponList.stream().noneMatch(i -> i.getId().equals(entry.getValue().getMemberCoupon().getId()))) {
                    tradeDTO.getStoreCoupons().remove(entry.getKey());
                }
            }
        }
    }

    /**
     * 判定优惠券是否可用 拼接无法使用原因
     *
     * @param tradeDTO     交易dto
     * @param memberCoupon 会员优惠券
     */
    private void available(TradeDTO tradeDTO, MemberCoupon memberCoupon) {
        if (memberCoupon == null) {
            return;
        }
        // 符合优惠券规则的商品列表
        List<CartSkuVO> filterSku = filterSku(tradeDTO.getCheckedSkuList(), memberCoupon);
        if (filterSku == null || filterSku.isEmpty()) {
            tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon,
                    "购物车中没有满足优惠券使用范围的优惠券"));
            return;
        }

        //过滤的商品总价
        Double filterPrice = 0.0;

        //计算符合优惠券规则的总金额
        for (CartSkuVO cartSkuVO : filterSku) {
            //计算折扣价格为，绿色积分价格+商品价格
            Double tempPrice = CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getFlowPrice(),cartSkuVO.getGreenScore());
            //减去运费
            tempPrice = CurrencyUtil.sub(tempPrice,cartSkuVO.getPriceDetailDTO().getFreightPrice());
            log.info("tempPrice---{}",tempPrice);
            filterPrice = CurrencyUtil.add(filterPrice,tempPrice);
            log.info("filterPrice---{}",filterPrice);
        }


        //满足条件判定
        if (filterPrice >= memberCoupon.getConsumeThreshold()) {
            tradeDTO.getCanUseCoupons().add(memberCoupon);
        } else {
            tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon,
                    "优惠券使用门槛不足，还差 ￥" +
                            StringUtils.formatPrice(CurrencyUtil.sub(memberCoupon.getConsumeThreshold(), filterPrice)) +
                            " 元"));
        }

    }

    /**
     * 按照优惠券的适用范围过滤过滤购物车商品信息
     *
     * @param cartSkuVOS   购物车中的产品列表
     * @param memberCoupon 会员优惠券
     * @return 按照优惠券的适用范围过滤的购物车商品信息
     */
    private List<CartSkuVO> filterSku(List<CartSkuVO> cartSkuVOS, MemberCoupon memberCoupon) {

        List<CartSkuVO> filterSku;
        //平台店铺过滤
        if (Boolean.TRUE.equals(memberCoupon.getPlatformFlag())) {
            filterSku = cartSkuVOS;
        } else {
            filterSku =
                    cartSkuVOS.stream().filter(cartSkuVO -> cartSkuVO.getStoreId().equals(memberCoupon.getStoreId())).collect(Collectors.toList());
        }
        if (filterSku == null || filterSku.isEmpty()) {
            return Collections.emptyList();
        }
        //优惠券类型判定
        switch (PromotionsScopeTypeEnum.valueOf(memberCoupon.getScopeType())) {
            case ALL -> {
                return filterSku;
            }
            case PORTION_GOODS ->
                //按照商品过滤
                    filterSku =
                            filterSku.stream().filter(cartSkuVO -> memberCoupon.getScopeId().contains(cartSkuVO.getGoodsSku().getId())).collect(Collectors.toList());
            case PORTION_SHOP_CATEGORY ->
                //按照店铺分类过滤
                    filterSku = this.filterPromotionShopCategory(filterSku, memberCoupon);
            case PORTION_GOODS_CATEGORY ->

                //按照店铺分类过滤
                    filterSku = filterSku.stream().filter(cartSkuVO -> {
                        //平台分类获取
                        String[] categoryPath = cartSkuVO.getGoodsSku().getCategoryPath().split(",");
                        //平台三级分类
                        String categoryId = categoryPath[categoryPath.length - 1];
                        return memberCoupon.getScopeId().contains(categoryId);
                    }).toList();
            default -> {
                return Collections.emptyList();
            }
        }
        return filterSku;
    }

    /**
     * 优惠券按照店铺分类过滤
     *
     * @param filterSku    过滤的购物车商品信息
     * @param memberCoupon 会员优惠
     * @return 优惠券按照店铺分类过滤的购物车商品信息
     */
    private List<CartSkuVO> filterPromotionShopCategory(List<CartSkuVO> filterSku, MemberCoupon memberCoupon) {
        return filterSku.stream().filter(cartSkuVO -> {
            if (CharSequenceUtil.isNotEmpty(cartSkuVO.getGoodsSku().getStoreCategoryPath())) {
                //获取店铺分类
                String[] storeCategoryPath = cartSkuVO.getGoodsSku().getStoreCategoryPath().split(",");
                for (String category : storeCategoryPath) {
                    //店铺分类只要有一项吻合，即可返回true
                    if (memberCoupon.getScopeId().contains(category)) {
                        return true;
                    }
                }
            }
            return false;
        }).toList();
    }

    /**
     * 渲染优惠券
     *
     * @param tradeDTO 购物车展示信息
     */
    private void renderCoupon(TradeDTO tradeDTO) {

        if (null != tradeDTO.getPromotionType()) {
            return;
        }

        //如果有勾选平台优惠券
        if (tradeDTO.getPlatformCoupon() != null) {
            if (Boolean.FALSE.equals(renderSku(tradeDTO, tradeDTO.getPlatformCoupon()))) {
                tradeDTO.setPlatformCoupon(null);
            }
        }
        //待清理的优惠券
        List<MemberCouponDTO> invalidCoupons = new ArrayList<>();
        //计算商家优惠券
        if (tradeDTO.getStoreCoupons() != null && tradeDTO.getStoreCoupons().size() > 0) {
            for (MemberCouponDTO memberCouponDTO : tradeDTO.getStoreCoupons().values()) {
                if (Boolean.FALSE.equals(renderSku(tradeDTO, memberCouponDTO))) {
                    invalidCoupons.add(memberCouponDTO);
                }
            }
        }
        //清理无效优惠券
        if (!invalidCoupons.isEmpty()) {
            invalidCoupons.forEach(memberCouponDTO -> {
                tradeDTO.getStoreCoupons().remove(memberCouponDTO.getMemberCoupon().getStoreId());
            });
        }
    }

    /**
     * 渲染sku优惠信息
     *
     * @param tradeDTO        交易DTO
     * @param memberCouponDTO 优惠券DTO
     */
    private Boolean renderSku(TradeDTO tradeDTO, MemberCouponDTO memberCouponDTO) {

        //过滤购物车商品信息
        List<CartSkuVO> couponSkuVO = filterSku(tradeDTO.getCheckedSkuList(), memberCouponDTO.getMemberCoupon());
        Double price = 0.0;
        //计算商品总价
        for (CartSkuVO cartSkuVO : couponSkuVO) {
            price = CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), price,cartSkuVO.getGreenScore());
        }
        //如果商品总价小于优惠券使用门槛，不可使用优惠券
        if (memberCouponDTO.getMemberCoupon().getConsumeThreshold() > price) {
            return false;
        }

        //处理极端情况，如果商品金额小于优惠券金额，则将优惠券金额设置为商品金额
        if (memberCouponDTO.getMemberCoupon().getPrice() > price) {
            memberCouponDTO.getMemberCoupon().setPrice(price);
        }


        //写入商品价格信息
        Map<String, Double> relationship = new HashMap<>();
        for (CartSkuVO cartSkuVO : couponSkuVO) {
            relationship.put(cartSkuVO.getGoodsSku().getId(), cartSkuVO.getPriceDetailDTO().getGoodsPrice());
        }
        memberCouponDTO.setRelationship(relationship);

        //处理 现金优惠券
        if (memberCouponDTO.getMemberCoupon().getCouponType().equals(CouponTypeEnum.PRICE.name())) {
            Map<String, Double> promotionPriceMap = PromotionPriceUtil.recountPrice(memberCouponDTO.getRelationship(),
                    memberCouponDTO.getMemberCoupon().getPrice());

            for (CartSkuVO cartSkuVO : couponSkuVO) {
                if (null != cartSkuVO.getPromotionTypeEnum()) {
                    cartSkuVO.getPriceDetailDTO().setCouponPrice(0D);
                }else {
                    //写入优惠券金额
                    cartSkuVO.getPriceDetailDTO().setCouponPrice(CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(),
                            promotionPriceMap.get(cartSkuVO.getGoodsSku().getId())));
                }

                //写入平台营销费用记录
                cartSkuVO.getPriceDetailDTO().addSiteMarketingCost(
                        SiteMarketingCost.builder()
                                .marketingCost(promotionPriceMap.get(cartSkuVO.getGoodsSku().getId()))
                                .commitmentPoint(memberCouponDTO.getMemberCoupon().getStoreCommission())
                                .description("优惠券-" + memberCouponDTO.getMemberCoupon().getId())
                                .build());
            }


        } else {
            // 循环购物车商品
            for (CartSkuVO item : couponSkuVO) {

                PriceDetailDTO priceDetailDTO = item.getPriceDetailDTO();

                // 打折金额=商品金额*折扣/10
                Double discountCouponPrice = CurrencyUtil.mul(priceDetailDTO.getGoodsPrice(),
                        CurrencyUtil.sub(1, CurrencyUtil.div(memberCouponDTO.getMemberCoupon().getDiscount(), 10, 3)));

                //平台券则写入店铺承担优惠券比例
                if (Boolean.TRUE.equals(memberCouponDTO.getMemberCoupon().getPlatformFlag())) {
                    priceDetailDTO.addSiteMarketingCost(
                            SiteMarketingCost.builder()
                                    .commitmentPoint(memberCouponDTO.getMemberCoupon().getStoreCommission())
                                    .marketingCost(discountCouponPrice)
                                    .description("优惠券-" + memberCouponDTO.getMemberCoupon().getCouponId())
                                    .build()
                    );
                }

                if (null != item.getPromotionTypeEnum()) {
                    priceDetailDTO.setCouponPrice(0D);
                }else {
                    priceDetailDTO.setCouponPrice(CurrencyUtil.add(priceDetailDTO.getCouponPrice(), discountCouponPrice));
                }

            }
        }
        return true;
    }


}
